const runner = (_gen) => {
  return new Promise((resolve, reject) => {
    let gen = _gen()
    _next()
    function _next(_last_res) {
      let res = gen.next(_last_res)

      if (!res.done) {
        let obj = res.value

        if (obj.then) {
          obj.then(res => {
            _next(res)
          },
          error => {
            reject(error)
          }
        )
      } else if (typeof obj === 'function') {
        if (obj.constructor.toString().startsWith('function GeneratorFunction')) {
          runner(obj).then(res => _next(res), reject)
        } else {
          _next(obj())
        }
      } else {
        _next(obj)
      }
      } else {
        resolve(res.value)
      }
    }
  })
}
